﻿using ServBus.ListForm2013.Common.XSNOperator;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;

namespace WinForm4AppGenerate
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnMainListSelect_Click(object sender, EventArgs e)
        {
            SelectSchema(tbMainList);
            if (!string.IsNullOrEmpty(tbMainList.Text))
            {
                mainListBox.DataSource = GetContentTypeList(tbMainList.Text);
            }
        }

        private void btnSubListSelect_Click(object sender, EventArgs e)
        {
            SelectSchema(tbSubList);
            if (!string.IsNullOrEmpty(tbSubList.Text))
            {
                List<string> subCTypeList = GetContentTypeList(tbSubList.Text);
                foreach (string subCType in subCTypeList)
                {
                    subListBox.Items.Add(subCType);
                }
            }
        }

        private void btnGenerate_Click(object sender, EventArgs e)
        {
            try
            {

                XListInfo mainListInfo = GetListInfo(tbMainList.Text, mainListBox.SelectedValue.ToString());
                List<XListInfo> subListInfos = new List<XListInfo>();
                if (!string.IsNullOrEmpty(tbSubList.Text))
                {
                    foreach (ListViewItem subCType in subListBox.Items)
                    {
                        subListInfos.Add(GetListInfo(tbSubList.Text, subCType.Text));
                    }
                    GenerateXSN(mainListInfo, subListInfos);
                }
                else
                {
                    GenerateXSN(mainListInfo);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void SelectSchema(TextBox pathTextBox)
        {
            //初始化一个OpenFileDialog类 
            OpenFileDialog fileDialog = new OpenFileDialog();
            fileDialog.Filter = "(*.xml)|*.xml";
            fileDialog.Multiselect = false;

            //判断用户是否正确的选择了文件 
            if (fileDialog.ShowDialog() == DialogResult.OK)
            {
                pathTextBox.Text = fileDialog.FileName;
            }
        }

        private List<String> GetContentTypeList(string sourceSchemaPath)
        {
            List<string> cTypeList = new List<string>();
            XmlDocument schemaXmlDocument = new XmlDocument();
            schemaXmlDocument.Load(sourceSchemaPath);
            XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(schemaXmlDocument.NameTable);
            xmlNamespaceManager.AddNamespace("sp", "http://schemas.microsoft.com/sharepoint/");
            XmlNodeList cTypeNodes = schemaXmlDocument.DocumentElement.SelectNodes("//sp:ContentType", xmlNamespaceManager);
            foreach (XmlNode cTypeNode in cTypeNodes)
            {
                cTypeList.Add(cTypeNode.Attributes["Name"].Value);
            }
            return cTypeList;
        }

        private XListInfo GetListInfo(string sourceSchemaPath, string cTypeName)
        {
            XmlDocument schemaXmlDocument = new XmlDocument();
            schemaXmlDocument.Load(sourceSchemaPath);
            XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(schemaXmlDocument.NameTable);
            xmlNamespaceManager.AddNamespace("sp", "http://schemas.microsoft.com/sharepoint/");

            //Initial ListInfo & ContentTypeInfo & FieldInfo
            //Create Main ListInfo
            XListInfo mListInfo = new XListInfo();
            XmlNode listNode = schemaXmlDocument.SelectSingleNode("/sp:List", xmlNamespaceManager);
            //GenerateListInfo()
            mListInfo.ListID = "{" + listNode.Attributes["Title"].Value + "}";
            mListInfo.ListTitle = listNode.Attributes["Title"].Value;
            mListInfo.UniqueName = FieldHelper.GetUniquefieldName(listNode.Attributes["Title"].Value.Replace(" ", "_"));

            //AddContentTypeInfo()
            XmlNode cTypeNode = listNode.SelectSingleNode("//sp:ContentType[@Name='" + cTypeName + "']", xmlNamespaceManager);
            ContentTypeInfo cTypeInfo = new ContentTypeInfo
            {
                ContentTypeId = cTypeNode.Attributes["ID"].Value,
                ContentTypeName = cTypeNode.Attributes["Name"].Value,
                UniqueName = FieldHelper.GetUniquefieldName((mListInfo.ListTitle + "_" + cTypeNode.Attributes["Name"].Value).Replace(" ", "_"))
            };
            mListInfo.ContentTypeInfoList.Add(cTypeInfo);

            //AddFieldInfoList
            XmlNodeList fieldNodesRef = cTypeNode.SelectNodes("//sp:FieldRefs/sp:FieldRef", xmlNamespaceManager);
            foreach (XmlNode fieldNodeRef in fieldNodesRef)
            {
                string fieldNodeXPath = string.Format("/sp:List/sp:MetaData/sp:Fields/sp:Field[@ID='{0}']",
                    fieldNodeRef.Attributes["ID"].Value);
                XmlNode fieldNode = schemaXmlDocument.SelectSingleNode(fieldNodeXPath, xmlNamespaceManager);

                if (fieldNode != null)
                {
                    string fieldType = fieldNode.Attributes["Type"].Value;
                    string fieldName = fieldNode.Attributes["Name"].Value;
                    string fieldDisplayName = fieldNode.Attributes["DisplayName"].Value;
                    #region switch fieldType
                    switch (fieldType)
                    {
                        case "Boolean":
                            BooleanFieldInfo boolfieldInfo = new BooleanFieldInfo();
                            SetFieldInfo(boolfieldInfo, fieldName, fieldDisplayName, mListInfo.ListTitle,
                                cTypeInfo.ContentTypeName, FieldInfoType.Boolean);
                            cTypeInfo.FieldInfoList.Add(boolfieldInfo);
                            break;
                        case "Choice":
                            DropdownFieldInfo choicefieldInfo = new DropdownFieldInfo();
                            SetFieldInfo(choicefieldInfo, fieldName, fieldDisplayName, mListInfo.ListTitle,
                                cTypeInfo.ContentTypeName, FieldInfoType.Dropdown);
                            //Set Choice
                            choicefieldInfo.ChoiceList = new List<string>();
                            XmlNodeList choiceNodes = fieldNode.SelectNodes("//sp:CHOICE", xmlNamespaceManager);
                            foreach (XmlNode choiceItem in choiceNodes)
                            {
                                choicefieldInfo.ChoiceList.Add(choiceItem.InnerText);
                            }
                            cTypeInfo.FieldInfoList.Add(choicefieldInfo);
                            break;
                        case "Currency":
                            CurrencyFieldInfo currencyfieldInfo = new CurrencyFieldInfo();
                            SetFieldInfo(currencyfieldInfo, fieldName, fieldDisplayName, mListInfo.ListTitle,
                                cTypeInfo.ContentTypeName, FieldInfoType.Currency);
                            cTypeInfo.FieldInfoList.Add(currencyfieldInfo);
                            break;
                        case "DateTime":
                            DateTimeFieldInfo datefieldInfo = new DateTimeFieldInfo();
                            SetFieldInfo(datefieldInfo, fieldName, fieldDisplayName, mListInfo.ListTitle,
                                cTypeInfo.ContentTypeName, FieldInfoType.DateTime);
                            cTypeInfo.FieldInfoList.Add(datefieldInfo);
                            break;
                        case "Lookup":
                            LookUpFieldInfo lookupfieldInfo = new LookUpFieldInfo();
                            SetFieldInfo(lookupfieldInfo, fieldName, fieldDisplayName, mListInfo.ListTitle,
                                cTypeInfo.ContentTypeName, FieldInfoType.LookUp);
                            lookupfieldInfo.LookupListName = fieldNode.Attributes["List"].Value.Substring(6);
                            lookupfieldInfo.LookupFieldName = fieldNode.Attributes["ShowField"].Value;
                            lookupfieldInfo._lookupSiteUrl = "";
                            //lookupfieldInfo._lookupListID = p_SPField.LookupList;
                            lookupfieldInfo._lookupListRelativeUrl = "{" + fieldNode.Attributes["List"].Value + "}";
                            cTypeInfo.FieldInfoList.Add(lookupfieldInfo);
                            break;
                        case "MultiChoice":
                            MultiChoiceFieldInfo mchoicefieldInfo = new MultiChoiceFieldInfo();
                            SetFieldInfo(mchoicefieldInfo, fieldName, fieldDisplayName, mListInfo.ListTitle,
                                cTypeInfo.ContentTypeName, FieldInfoType.MultiChoice);
                            //Set Choice
                            XmlNodeList mchoiceNodes = fieldNode.SelectNodes("//sp:CHOICE", xmlNamespaceManager);
                            foreach (XmlNode choiceItem in mchoiceNodes)
                            {
                                mchoicefieldInfo.ChoiceList.Add(choiceItem.InnerText);
                            }
                            cTypeInfo.FieldInfoList.Add(mchoicefieldInfo);
                            break;
                        case "Note":
                            NoteFieldInfo notefieldInfo = new NoteFieldInfo();
                            SetFieldInfo(notefieldInfo, fieldName, fieldDisplayName, mListInfo.ListTitle,
                                cTypeInfo.ContentTypeName, FieldInfoType.Note);
                            notefieldInfo.richText = true;
                            cTypeInfo.FieldInfoList.Add(notefieldInfo);
                            break;
                        case "Number":
                            NumberFieldInfo numberfieldInfo = new NumberFieldInfo();
                            SetFieldInfo(numberfieldInfo, fieldName, fieldDisplayName, mListInfo.ListTitle,
                                cTypeInfo.ContentTypeName, FieldInfoType.Number);
                            cTypeInfo.FieldInfoList.Add(numberfieldInfo);
                            break;
                        case "Text":
                            TextFieldInfo testfieldInfo = new TextFieldInfo();
                            SetFieldInfo(testfieldInfo, fieldName, fieldDisplayName, mListInfo.ListTitle,
                                cTypeInfo.ContentTypeName, FieldInfoType.Text);
                            cTypeInfo.FieldInfoList.Add(testfieldInfo);
                            break;
                        case "URL":
                            UrlFieldInfo urlfieldInfo = new UrlFieldInfo();
                            SetFieldInfo(urlfieldInfo, fieldName, fieldDisplayName, mListInfo.ListTitle,
                                cTypeInfo.ContentTypeName, FieldInfoType.Url);
                            cTypeInfo.FieldInfoList.Add(urlfieldInfo);
                            break;
                        case "User":
                        case "UserMulti":
                            UserFieldInfo userfieldInfo = new UserFieldInfo();
                            SetFieldInfo(userfieldInfo, fieldName, fieldDisplayName, mListInfo.ListTitle,
                                cTypeInfo.ContentTypeName, FieldInfoType.User);
                            cTypeInfo.FieldInfoList.Add(userfieldInfo);
                            break;
                    }
                    #endregion
                }
            }

            mListInfo.ContentTypeInfoList[0].ViewFieldList = mListInfo.ContentTypeInfoList[0].FieldInfoList;

            return mListInfo;
        }

        private void GenerateXSN(XListInfo mListInfo)
        {
            #region Generate XSN
            string xsnTemplatePath = Environment.CurrentDirectory;
            xsnTemplatePath = xsnTemplatePath.Remove(xsnTemplatePath.Length - 9) + "xsn_template\\";
            XSNOperator xsnOperator = new XSNOperator
            {
                XSNTemplateFolder = xsnTemplatePath,
                MListInfo = mListInfo
            };

            xsnOperator.GenerateXSN();
            #endregion
            System.Threading.Thread.Sleep(500);
            Process.Start("explorer.exe", xsnOperator.SaveFolder + "\\template\\");
        }

        private void GenerateXSN(XListInfo mListInfo, List<XListInfo> sListInfos)
        {
            #region Generate XSN
            string xsnTemplatePath = Environment.CurrentDirectory;
            xsnTemplatePath = xsnTemplatePath.Remove(xsnTemplatePath.Length - 9) + "xsn_template\\";
            XSNOperator xsnOperator = new XSNOperator
            {
                XSNTemplateFolder = xsnTemplatePath,
                MListInfo = mListInfo,
                SListsInfo = sListInfos
            };

            xsnOperator.GenerateXSN();
            #endregion
            System.Threading.Thread.Sleep(500);
            Process.Start("explorer.exe", xsnOperator.SaveFolder + "\\template\\");
        }

        private void SetFieldInfo(XFieldInfo fieldInfo, string fieldName, string fieldDisplayName, string ListTitle, string ContentTypeName, FieldInfoType fType)
        {
            fieldInfo.InternalName = fieldName;
            fieldInfo.DisplayName = fieldDisplayName;
            fieldInfo.FieldInfoType = fType;
            fieldInfo.ReadOnly = false;
            fieldInfo.Hidden = false;
            fieldInfo.DefaultValue = "";
            fieldInfo.UniqueName =
string.Format("{0}_{1}_{2}", ListTitle, ContentTypeName, fieldName).Replace(" ", "_");

            fieldInfo.UniqueName = FieldHelper.GetUniquefieldName(fieldInfo.UniqueName);
        }
    }
}
